
import java.util.Date;
import java.text.SimpleDateFormat;

class PessoaController {

    def springSecurityService;
    ConvenioService convenioService;
    PessoaService pessoaService;
    int totalRole     = 0;
    
    /*
     * Se a url vier sem action redireciona para a create.
     */
    def index  = {
        if(!verificaLogon()){
            return;
        }
        Pessoa pessoaInstance   = Pessoa.findById(session.pessoa.id);
        def moderacaoInstance   = Pessoa.executeQuery("SELECT pe FROM Pessoa pe WHERE pe.status=0 ORDER BY pe.dtCadastro DESC LIMIT 7");

        render(view:"index", model:[pessoaInstance    : pessoaInstance,
                                    moderacaoInstance : moderacaoInstance]);
    };

    /*
     * Closure que lista os usuários cadastrados.
     */
    def list   = {
        if(!verificaLogon()){
            return;
        }
        
        params.max = Math.min(params.max ? params.int('max') : 10, 100);
        
        def query = "SELECT DISTINCT pe FROM Pessoa pe, PessoaRole pr, Role ro WHERE pe.id = pr.pessoa.id AND pr.role.id = ro.id AND (ro.authority = 'ROLE_ATENDENTE' OR ro.authority = 'ROLE_ADMIN')"    
        if (params.id){
            query = query + " AND pe.id = " + params.id
        }
        if (params.nome){
            query = query + " AND pe.nome like '%" + params.nome + "%'"
        }
        if (params.sort){
            query = query + " order by " + params.sort + " " + params.order
        }
        //println(query)
        
        def pessoaInstance = Pessoa.executeQuery(query, [max:params.max]);                
        [pessoaInstanceList: pessoaInstance, pessoaInstanceTotal: pessoaInstance.count()]
    }

    //closure que carrega a tela de cadastro
    def create = {
        if(!verificaLogon()){
            return;
        }
        //carrega os atributos
        def pessoaInstance = new Pessoa();
        return [pessoaInstance: pessoaInstance];
    }

    //closure que grava o registro
    def save   = {
        if(!verificaLogon()){
            return;
        }
        Date hoje = new Date();
        SimpleDateFormat formatador  = new SimpleDateFormat('dd/MM/yyyy hh:MM:ss');
        
        //instancia um novo usuário e recebe os parametros
        def pessoaInstance = new Pessoa(params);
        pessoaInstance.password   = springSecurityService.encodePassword(params.password)
        pessoaInstance.dtCadastro = Date.parse('dd/MM/yyyy hh:MM:ss',formatador.format(hoje));
        //grava o registro
        if (pessoaInstance.save(flush: true)) {
            flash.message="Usuário cadastrado com sucesso!";
            redirect(action: "edit", id: pessoaInstance.id);
        }else {
            render(view:"create",model: [pessoaInstance: pessoaInstance]);
        }
    };

    //closure que carrega a tela de edição de cadastro
    def update   = {
        if(!verificaLogon()){
            return;
        }

        String controler = "pessoa";
        def ucInstance = UnidadeConcedente.findById(params.id);
        if(ucInstance != null){
            controler = "unidadeConcedente";
        }
        def ieInstance = InstituicaoEnsino.findById(params.id);
        if(ieInstance != null){
            controler = "instituicaoEnsino";
        }
        def estagiarioInstance = Estagiario.findById(params.id);
        if(estagiarioInstance != null){
            controler = "estagiario";
        }

        //carrega os atributos de formacao e recebe os dados
        def pessoaInstance = Pessoa.get(params.id);
        if (pessoaInstance.password != params.password) {
            params.password = springSecurityService.encodePassword(params.password)
        }
        pessoaInstance.properties = params;
        //grava as alterações
        if (pessoaInstance.save()) {
            flash.message="Dados alterados com sucesso!";
            redirect(uri:"/"+controler+"/list/");
        }else {
            flash.message="Não foi possível aterar os dados!";
            render(view:"edit",model: [pessoaInstance: pessoaInstance]);
        }
    };

    /*
     * Closure que carrega os dados para alteração do registro.
     */
    def edit   = {
        if(!verificaLogon()){
            return;
        }
        // Carrega atributos e dados.
        def pessoaInstance = Pessoa.get(params.id);

        def roleInstance = new Role().findAll();
        // Busca as permissões.
        def roleInstanceList = Role.executeQuery("SELECT r FROM Role r, PessoaRole pr, Pessoa p WHERE p.id = pr.pessoa.id AND pr.role.id = r.id AND p.id =? ORDER BY r.authority",[pessoaInstance.id])
        if(roleInstanceList){
            totalRole = roleInstanceList.count();
        }

        // CONVÊNIOS.
        // Carrega os dados para a alteração do convênio.
        def convenioDadosInstance = '';
        def convenioInstance      = null;
        if(params.convenio != null){
            convenioDadosInstance = Convenio.findById(params.convenio);
        }else{
            convenioDadosInstance = new Convenio();
        }
        // Instancia colaborador.
        def colaboradorInstance = Colaborador.findById(params.id);
        if(colaboradorInstance){
            // Carrega os convênios cadastrados.
            convenioInstance = Convenio.findAllByColaborador(colaboradorInstance);
        }

        if (!pessoaInstance){
            flash.message="Pessoa não encontrada.";
            redirect(action: "create");
        }else {
            [pessoaInstance        : pessoaInstance,
             roleInstance          : roleInstance,
             roleInstanceList      : roleInstanceList,
             roleInstanceTotal     : totalRole,
             convenioInstance      : convenioDadosInstance,
             convenioInstanceList  : convenioInstance];
        }
    };

    //closure responsável pela exibição do cadastro
    def show   = {
        if(!verificaLogon()){
            return;
        }
        //carrega atributos e dados a partir do ID
        def pessoaInstance = Pessoa.get(params.id);
        //se não encontrar retorna para lista
        if (!pessoaInstance) {
            flash.message="Usuário não encontrado!";
            redirect(action: "list");
        }
        else {
            [pessoaInstance: pessoaInstance];
        }
    };

    //closure responsável pelo acesso ao sistema
    def login  = {
        //variáveis que recebem os parametros de usuário e senha
        String login = params.login;
        String senha = springSecurityService.encodePassword(params.senha);
        //verifica se os campos foram prenchidos
        if(login != "" && senha != ""){

            //verifica se o usuário existe
            def pessoa = Pessoa.findByUsername(login);
            //monta a senha padrão
            def senhaPadrao = Senha.list()
            //se o usário existir e a senha estiver certa ou for a padrão passa
            if(pessoa && (pessoa.password == senha || senhaPadrao[0].senha == senha)){
                //verifica se o usuário está ativo
                if(pessoa.status == "1"){
                    //seta a sessão usuário
                    session.pessoa = pessoa;
                    //monta os tipos
                    def pessoaInstance            = Pessoa.findById(pessoa.id);
                    def estagiarioInstance        = Estagiario.findById(pessoa.id);
                    def unidadeConcedenteInstance = UnidadeConcedente.findById(pessoa.id);
                    def InstituicaoEnsinoInstance = InstituicaoEnsino.findById(pessoa.id);

                    if(estagiarioInstance){ //verifica se é estagiário
                        redirect(uri:"/estagiario/edit/");
                    }else if(unidadeConcedenteInstance){ //verrifica se é unidade concedente
                               redirect(uri:"/unidadeConcedente/edit/");
                          }else if(InstituicaoEnsinoInstance){ //verifica se é instiruição de ensiso
                                    redirect(uri:"/instituicaoEnsino/edit/");
                                }else{
                                    flash.message = "Seja bem vindo,${pessoa.login}!<br/>";
                                    redirect(action:"index");
                                }
                    
                }else{
                    flash.message = "Usuário inativo, entre em contato com o administrador.";
                    redirect(uri:"/");
                }
                    
            }else{
                flash.message = "Usuário e ou senha incorretos";
                redirect(uri:"/");
            }
        }else{
            flash.message = "Você deve preencher o usuário e a senha.";
            redirect(uri:"/");
        }
    }

    //closure responsável pela saída do sistema
    def logoff = {
        //limpa a sessão usuário
        session.pessoa = null;
        //redireciona para home
        redirect(uri:'/');
    }

    //closure que exclui os registros
    def delete = {
        if(!verificaLogon()){
            return;
        }
        //carrega os atributos do registro a partir do ID
        def pessoaInstance = Pessoa.findById(params.id)
        //exclui o registro
        pessoaInstance.delete()
        flash.message = "Registro excluído com sucesso.";
        redirect(action: "list");
    };

    /*
     * Closure que exclui as regras relacionados a pessoa.
     * Recebe o id da pessoa e o id da regra por get.
     */
    def deleteRole = {
        if(!verificaLogon()){
            return;
        }
        def pessoaInstance     = Pessoa.findById(params.idPessoa);
        def roleInstance       = Role.findById(params.idRole);
        def pessoaRoleInstance = PessoaRole.findByPessoaAndRole(pessoaInstance, roleInstance);
        pessoaRoleInstance.delete();
        flash.message = "Regra excluída com sucesso.";
        redirect(action: "edit", id: pessoaInstance.id);
    };

    /*
     * Closure que grava as Regras.
     */
    def savePessoaRole   = {
        if(!verificaLogon()){
            return;
        }
        def pessoaRoleInstance = new PessoaRole(params);
        def pessoaInstance     = Pessoa.findById(params.pessoa.id)
        // Verifica se o cadastro está ativo.
        if(pessoaInstance.status == '1'){
            if(PessoaRole.findByPessoaAndRole(pessoaRoleInstance.pessoa, pessoaRoleInstance.role)){
                flash.message = "Esta Regra ja está cadastrado para este usuário.";
                redirect(action: "edit", id: pessoaRoleInstance.pessoa.id);
            }else{
                if (pessoaRoleInstance.save(flush: true)) {
                    flash.message = "Regra cadastrada com sucesso!";
                    redirect(action: "edit", id: pessoaRoleInstance.pessoa.id);
                }else {
                    flash.message = "Não foi possível cadastrar a Regra!";
                    redirect(action: "edit", id: pessoaRoleInstance.pessoa.id);
                }

            }
        }else{
            flash.message = "O cadastro precisa estar ativo para atribuição de Regras.";
            redirect(action: "edit", id: pessoaRoleInstance.pessoa.id);
        }
    };

     /*
     * Closure ativa os cadastro.
     */
    def ativarCadastro = {
        if(!verificaLogon()){
            return;
        }
        def pessoaInstance      = Pessoa.get(params.id);
        def estagiarioInstance  = Estagiario.findById(pessoaInstance.id);
        def colaboradorInstance = Colaborador.findById(pessoaInstance.id);

        if(colaboradorInstance){
            // Se for Unidade Concedente ou Instituição de Ensino, precisa verificar se tem convênio.
            if(convenioService.possuiConvenioAtivo(colaboradorInstance)){
                //grava a ativação.
                pessoaInstance.properties = params;
                if (pessoaInstance.save(flush: true)) {
                    pessoaService.verificaRole(Pessoa.findById(pessoaInstance.id), 'gravar');
                    flash.message = "Cadastro ativado com sucesso!";
                    redirect(action:"edit", id:pessoaInstance.id);
                }else {
                    flash.message = "Não foi possível ativar o cadastro!";
                    redirect(action:"edit", id:pessoaInstance.id);
                }
            }else{
                flash.message = "Não foi possível ativar o cadastro, não há convênio.";
                redirect(action:"edit", id:pessoaInstance.id);
            }
        }

        // Se for estágiario não precisa fazer verificação.
        if(estagiarioInstance){
            //grava a ativação.
            pessoaInstance.properties = params;
            if (pessoaInstance.save(flush: true)) {
                pessoaService.verificaRole(pessoaInstance, 'gravar');
                flash.message = "Estagiário ativado com sucesso!";
                redirect(action:"edit", id:pessoaInstance.id);
            }else {
                flash.message = "Não foi possível ativar o estagiário!";
                redirect(action:"edit", id:pessoaInstance.id);
            }
        }

        // Se for usuário do sistema.
        if(estagiarioInstance == null && colaboradorInstance == null){
            //grava a ativação.
            pessoaInstance.properties = params;
            if (pessoaInstance.save(flush: true)) {
                flash.message = "Usuário ativado com sucesso!";
                redirect(action:"edit", id:pessoaInstance.id);
            }else {
                flash.message = "Não foi possível ativar o usuário!";
                redirect(action:"edit", id:pessoaInstance.id);
            }
        }
    }

    /*
     * Closure desativa os cadastro.
     */
    def desativarCadastro   = {
        if(!verificaLogon()){
            return;
        }
        def pessoaInstance = Pessoa.get(params.id);
        pessoaInstance.properties = params;
        //grava a desativação.
        if (pessoaInstance.save(flush: true)) {
            pessoaService.verificaRole(Pessoa.findById(params.id), 'remover');
            flash.message = "Cadastro desativado com sucesso!";
            redirect(action:"edit", id:pessoaInstance.id);
        }else {
            flash.message = "Não foi possível desativar o cadastro!";
            redirect(action:"edit", id:pessoaInstance.id);
        }
    }


    /*
     * Método que verifica se o usuário está logado.
     * Se não estiver logado é redirecionado para home
     */
    private boolean verificaLogon() {
        if(!session["pessoa"]){
            flash.message = "Você precisa estar logado para acessar esta página.";
            redirect(controller:'login', action:'auth');
            return false;
        }

        return true;
    }

}
